﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using LibCommon;
using RTCCore;

namespace LibRTC.Core.MessageMap.MediaEvent {
    public class VideoHandler : SimpleMessageHandler
    {
        private static ILogger LOGGER = LoggerFactory.GetLogger("VideoHandler", null);

        private RTCCoreClient _coreClient;

        private IVideoEvent _videoEvent;

        public VideoHandler()
        {
            _rtcEvent = RTC_EVENT.RTCE_MEDIA;
            _name = "VideoHandler";
        }

        public void SetRTCCoreClient(RTCCoreClient client)
        {
            Debug.Assert(null != client);
            _coreClient = client;
        }

        public void SetIVideoEvent(IVideoEvent videoEvent) {
            Debug.Assert(null != videoEvent);
            _videoEvent = videoEvent;
        }

        public override void Process(RTC_EVENT rtcEventType, object rtcEvent)
        {
            Debug.Assert(RTC_EVENT.RTCE_MEDIA == rtcEventType);
            Debug.Assert(null != rtcEvent);
            Debug.Assert(rtcEvent is IRTCMediaEvent);

            LOGGER.LogDebug("VideoHandler Event");

            IRTCMediaEvent mediaEvent = (IRTCMediaEvent)rtcEvent;

            switch (mediaEvent.EventType) {
                case RTC_MEDIA_EVENT_TYPE.RTCMET_STARTED:
                    OnVideStart(mediaEvent);
                    break;

                case RTC_MEDIA_EVENT_TYPE.RTCMET_STOPPED:
                    OnVideoStop(mediaEvent);
                    return;

                case RTC_MEDIA_EVENT_TYPE.RTCMET_FAILED:
                    LOGGER.LogError("RTCMET_FAILED");
                    return;

                default:
                    return;                    
            }
        }

        private void OnVideStart(IRTCMediaEvent mediaEvent) {

            Debug.Assert(null != mediaEvent);
            Debug.Assert(null != _videoEvent);

            int mediaCapabilities = _coreClient.RTCClient.MediaCapabilities;

            RTC_VIDEO_DEVICE device ;

            IVideoWindow videoWindow = null;

            switch (mediaEvent.MediaType) {

                case RTCConst.RTCMT_VIDEO_SEND:
                    device = RTC_VIDEO_DEVICE.RTCVD_PREVIEW;

                    if (0 != (mediaCapabilities & RTCConst.RTCMT_VIDEO_SEND)){
                        videoWindow = _coreClient.RTCClient.get_IVideoWindow(device);    
                    }

                    _videoEvent.OnStartSendVideo(device,mediaCapabilities,videoWindow);

                    break;

                case RTCConst.RTCMT_VIDEO_RECEIVE:
                    device = RTC_VIDEO_DEVICE.RTCVD_RECEIVE;
                    if (0 != (mediaCapabilities & RTCConst.RTCMT_VIDEO_RECEIVE))
                    {
                        videoWindow = _coreClient.RTCClient.get_IVideoWindow(device);
                    } 
                    _videoEvent.OnStartReceiveVideo(device,mediaCapabilities,videoWindow);
                    break;

                default:
                    // we do not deal with other media here
                    return;
            }         
        }

        private void OnVideoStop(IRTCMediaEvent mediaEvent) {

            Debug.Assert(null != mediaEvent);
            Debug.Assert(null != _videoEvent);

            switch (mediaEvent.MediaType)
            {

                case RTCConst.RTCMT_VIDEO_SEND:
                    _videoEvent.OnStopSendVideo();
                    break;

                case RTCConst.RTCMT_VIDEO_RECEIVE:
                    _videoEvent.OnStopReceiveVideo();
                    break;

                default:
                    // we do not deal with other media here
                    return;
            }            
        }
    }
}